﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

using KC.Framework.Extension;
using KC.Framework.Tenant;
using KC.Service.Account;
using KC.Service.Core;
using KC.DTO.Account;
using KC.DTO.Core;
using KC.Service.Core.DTO.Search;
using KC.Framework.Base;

namespace KC.WebApi.Account.Controllers
{
    [Authorize]
    public class AccountApiController : MVC.Core.Controllers.WebApiBaseController
    {
        private const string ServiceName = "KC.WebApi.Account.Controllers.AccountController";

        private IAccountService AccountService => ServiceProvider.GetService<IAccountService>();
        private ISysManageService SysManageService => ServiceProvider.GetService<ISysManageService>();
        private IRoleService RoleService => ServiceProvider.GetService<IRoleService>();
        private IMenuService MenuService => ServiceProvider.GetService<IMenuService>();
        private IPermissionService PermissionService => ServiceProvider.GetService<IPermissionService>();

        public AccountApiController(
            Tenant tenant,
            IServiceProvider serviceProvider,
            ILogger<AccountApiController> logger)
            : base(tenant, serviceProvider, logger)
        {
        }

        #region 角色信息

        /// <summary>
        /// 获取角色Id列表下的所有菜单
        /// </summary>
        /// <param name="roleIds">角色Id列表</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetUserMenusByRoleIds")]
        public async Task<ServiceResult<List<MenuNodeSimpleDTO>>> GetUserMenusByRoleIds([FromBody]List<string> roleIds)
        {
            return await GetServiceResultAsync(async () =>
            {
                return await RoleService.GetUserMenusByRoleIdsAsync(roleIds);
            });
        }
        /// <summary>
        /// 获取角色Id列表下的所有权限
        /// </summary>
        /// <param name="roleIds">角色Id列表</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetUserPermissionsByRoleIds")]
        public async Task<ServiceResult<List<PermissionSimpleDTO>>> GetUserPermissionsByRoleIds([FromBody]List<string> roleIds)
        {
            return await GetServiceResultAsync(async () =>
            {
                return await RoleService.GetUserPermissionsByRoleIdsAsync(roleIds);
            });
        }

        /// <summary>
        /// 获取角色列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("GetAllSimpleRoles")]
        public async Task<ServiceResult<List<RoleSimpleDTO>>> GetAllSimpleRoles()
        {
            return await GetServiceResultAsync(async () =>
            {
                return await RoleService.GetAllSimpleRolesAsync();
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="roleNames"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetRolesWithUsersByNames")]
        public ServiceResult<List<RoleDTO>> GetRolesWithUsersByNames([FromBody]List<string> roleNames)
        {
            return GetServiceResult(() =>
            {
                return RoleService.GetRolesWithUsersByNames(roleNames);
            });
        }

        /// <summary>
        /// 获取角色的分页列表
        /// </summary>
        /// <param name="name">角色名</param>
        /// <param name="appId">应用Id</param>
        /// <param name="pageIndex">分页页码</param>
        /// <param name="pageSize">分页大小</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetPagenatedRolesByName")]
        public ServiceResult<PaginatedBaseDTO<RoleDTO>> GetPagenatedRolesByName(string name, string appId, int pageIndex, int pageSize)
        {
            return GetServiceResult(() =>
            {
                var appid = Guid.Empty;
                if (!string.IsNullOrEmpty(appId))
                {
                    var success = Guid.TryParse(appId, out appid);
                    if (!success)
                    {
                        appid = Guid.Empty;
                    }
                }
                return RoleService.GetPagenatedRoleList(name, pageIndex, pageSize, true);
            });
        }
        
        /// <summary>
        /// 根据角色名称，获取角色信息（包含所有角色的用户）
        /// </summary>
        /// <param name="roleName">角色名称</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetRoleWithUsersByName")]
        public ServiceResult<RoleDTO> GetRoleWithUsersByName(string roleName)
        {
            return GetServiceResult(() =>
            {
                return RoleService.GetRoleWithUsersByName(roleName);
            });
        }

        /// <summary>
        /// 保存应用的权限数据
        /// </summary>
        /// <param name="permissions"></param>
        /// <param name="appId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("SavePermissions")]
        public async Task<ServiceResult<bool>> SavePermissionsAsync([FromBody]List<PermissionDTO> permissions, Guid appId)
        {
            return await GetServiceResultAsync(async () =>
            {
                return await PermissionService.SavePermissionsAsync(permissions, appId);
            });
        }

        /// <summary>
        /// 保存应用的菜单数据
        /// </summary>
        /// <param name="menus"></param>
        /// <param name="appId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("SaveMenus")]
        public async Task<ServiceResult<bool>> SaveMenusAsync([FromBody]List<MenuNodeDTO> menus, Guid appId)
        {
            return await GetServiceResultAsync(async () =>
            {
                return await MenuService.SaveMenusAsync(menus, appId);
            });
        }
        #endregion

        #region 租户内部的员工信息
        /// <summary>
        /// 获取所有用户的简单信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("GetAllSimpleUsers")]

        public ServiceResult<List<UserDTO>> GetAllSimpleUsers()
        {
            return GetServiceResult(() =>
            {
                return AccountService.FindAllUsersNoInclude();
            });
        }

        /// <summary>
        /// 获取所有员工的详细信息（包含：所属角色及组织架构）
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("GetAllUsersWithRolesAndOrgs")]

        public ServiceResult<List<UserDTO>> GetAllUsersWithRolesAndOrgs()
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetAllUsersWithRolesAndOrgs();
            });
        }

        /// <summary>
        /// 获取企业内部员工的联系方式
        /// </summary>
        /// <param name="id">用户Id</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetUserContactInfoById")]
        public ServiceResult<UserContactInfoDTO> GetUserContactInfoById(string id)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetUserContactInfoById(id);
            });
        }
        /// <summary>
        /// 根据用户Id列表，获取所有员工
        /// </summary>
        /// <param name="userIds">用户Id列表</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetUsersByIds")]

        public ServiceResult<List<UserDTO>> GetUsersByIds([FromBody]List<string> userIds)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetUsersByIds(userIds);
            });
        }
        /// <summary>
        /// 根据组织架构Id，获取该组织下的所有员工
        /// </summary>
        /// <param name="orgId">组织Id</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetUsersByOrgId")]

        public ServiceResult<List<UserDTO>> GetUsersByOrgId(int orgId)
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetUsersByOrgId(orgId);
            });
        }
        /// <summary>
        /// 根据组织架构Id列表，获取所有组织的下的所有员工
        /// </summary>
        /// <param name="orgIds">所有组织的Id列表</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetUsersByOrgIds")]

        public ServiceResult<List<UserDTO>> GetUsersByOrgIds([FromBody]List<int> orgIds)
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetUsersByOrgIds(orgIds);
            });
        }
        /// <summary>
        /// 获取所有组织的下的所有员工
        /// </summary>
        /// <param name="roleIds">所有组织的Id列表</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetUsersByRoleIds")]

        public ServiceResult<List<UserDTO>> GetUsersByRoleIds([FromBody]List<string> roleIds)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetUsersByRoleIds(roleIds);
            });
        }

        /// <summary>
        /// 根据用户名列表，查询的所有员工
        /// </summary>
        /// <param name="names">用户名列表</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetUsersByNames")]

        public ServiceResult<List<UserDTO>> GetUsersByDisplayNames([FromBody]List<string> names)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetUsersByNames(names);
            });
        }
        /// <summary>
        /// 根据用户邮箱列表，查询的所有员工
        /// </summary>
        /// <param name="emails">用户邮箱列表</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetUsersByEmails")]

        public ServiceResult<List<UserDTO>> GetUsersByEmails([FromBody]List<string> emails)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetUsersByEmails(emails);
            });
        }
        /// <summary>
        /// 获取该用户所属的所有组织信息
        /// </summary>
        /// <param name="userId">用户Guid</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetUserWithOrganizationsByUserId")]

        public ServiceResult<UserDTO> GetUserWithOrganizationsByUserId(string userId)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetUserWithOrganizationsByUserId(userId);
            });
        }

        /// <summary>
        /// 通过用户名获取用户邮箱
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetUserByUserName")]

        public ServiceResult<UserDTO> GetUserByUserName(string userName)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetUserByUserName(userName);
            });
        }

        /// <summary>
        /// 获取用户的简单数据（包含：所属的组织架构列表，不包含：系统用参数--邮箱是否确定、加密密码等等）
        /// </summary>
        /// <param name="userId">用户Guid</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetSimpleUserWithOrganizationsByUserId")]
        public ServiceResult<UserSimpleDTO> GetSimpleUserWithOrganizationsByUserId(string userId)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetSimpleUserWithOrgAndRoleNameByUserId(userId);
            });
        }

        [HttpPost]
        [Route("GetSimpleUserWithOrgAndRoleNameByUserId")]
        public ServiceResult<UserSimpleDTO> GetSimpleUserWithOrgAndRoleNameByUserId([FromBody]string userId)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetSimpleUserWithOrgAndRoleNameByUserId(userId);
            });
        }
        /// <summary>
        /// 修改租户的系统管理员的默认密码：123456
        /// </summary>
        /// <param name="password"></param>
        /// <param name="adminEmail"></param>
        /// <param name="adminPhone"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("ChangeAdminRawInfoAsync")]
        public async Task<ServiceResult<bool>> ChangeAdminRawInfoAsync(string password, string adminEmail, string adminPhone)
        {
            try
            {
                var result = await AccountService.ChangeAdminRawInfoAsync(password, adminEmail, adminPhone);
                return result.Succeeded
                    ? new ServiceResult<bool>(ServiceResultType.Success, string.Empty, true)
                    : new ServiceResult<bool>(ServiceResultType.Error, result.Errors.ToCommaSeparatedStringByFilter(m => m.Description), false);
            }
            catch (Exception ex)
            {
                var message = string.Format("调用服务({0})的方法({1})操作{2}。",
                    ServiceName, "ChangeAdminRawInfo", "失败，错误消息为：" + ex.Message);
                Logger.LogError(message);
                return new ServiceResult<bool>(ServiceResultType.Error, message);
            }
        }

        [HttpGet]
        [Route("ChangePasswordAsync")]
        public async Task<ServiceResult<bool>> ChangePasswordAsync(string userId, string currentPassword, string newPassword)
        {
            try
            {
                var result = await AccountService.ChangePasswordAsync(userId, currentPassword, newPassword);
                return result.Succeeded
                    ? new ServiceResult<bool>(ServiceResultType.Success, string.Empty, true)
                    : new ServiceResult<bool>(ServiceResultType.Error, result.Errors.ToCommaSeparatedStringByFilter(m => m.Description), false);
            }
            catch (Exception ex)
            {
                var message = string.Format("调用服务({0})的方法({1})操作{2}。",
                    ServiceName, "ChangePasswordAsync", "失败，错误消息为：" + ex.Message);
                Logger.LogError(message);
                return new ServiceResult<bool>(ServiceResultType.Error, message);
            }
        }

        [HttpGet]
        [Route("ChangeMailPhoneAsync")]
        public async Task<ServiceResult<bool>> ChangeMailPhoneAsync(string userId, string email, string phone)
        {
            try
            {
                var result = await AccountService.ChangeMailPhoneAsync(userId, email, phone);
                return result.Succeeded
                    ? new ServiceResult<bool>(ServiceResultType.Success, string.Empty, true)
                    : new ServiceResult<bool>(ServiceResultType.Error, result.Errors.ToCommaSeparatedStringByFilter(m => m.Description), false);
            }
            catch (Exception ex)
            {
                var message = string.Format("调用服务({0})的方法({1})操作{2}。",
                    ServiceName, "ChangePasswordAsync", "失败，错误消息为：" + ex.Message);
                Logger.LogError(message);
                return new ServiceResult<bool>(ServiceResultType.Error, message);
            }
        }
        #endregion

        #region 组织架构及其员工
        /// <summary>
        /// 获取所有部门信息(不是树状结构)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("GetAllOrganization")]
        public ServiceResult<List<OrganizationDTO>> GetAllOrganization()
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetAllOrganization();
            });
        }

        /// <summary>
        /// 获取所有的部门信息（部门树结构：包含下属部门）
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("GetRootOrganizations")]
        public ServiceResult<List<OrganizationDTO>> GetRootOrganizations()
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetAllOrganizationTrees();
            });
        }
        
        /// <summary>
        /// 获取所有的部门信息及下属员工
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("GetOrganizationsWithUsers")]
        public ServiceResult<List<OrganizationDTO>> GetOrganizationsWithUsers()
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetOrganizationsWithUsers();
            });
        }

        /// <summary>
        /// 根据组织Id列表，获取所有的部门信息（部门树结构，包含其下属所有的部门信息：递归查询）
        /// </summary>
        /// <param name="ids">组织Id列表</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetNestOrganizationsByIds")]
        public ServiceResult<List<OrganizationDTO>> GetNestOrganizationsByIds([FromBody]List<int> ids)
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetOrganizationTreesByIds(ids);
            });
        }

        /// <summary>
        /// 根据部门父节点Id，获取所属部门及其下属人员
        /// </summary>
        /// <param name="orgfid">部门父节点Id</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetUserByorgFid")]
        public ServiceResult<List<OrganizationDTO>> GetUserByorgFid(string orgfid)
        {
            return GetServiceResult(() =>
            {
                var org = SysManageService.GetOrganizationByFid(orgfid);
                org.Users = SysManageService.GetUsersByOrgIdWithoutOrg(org.id);

                return new List<OrganizationDTO>() { org };
            });
        }

        /// <summary>
        /// 获取所有的角色下的部门及下属员工
        /// </summary>
        /// <param name="roleIds">角色Id列表</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetOrganizationsWithUsersByRoleIds")]
        public ServiceResult<List<OrganizationDTO>> GetOrganizationsWithUsersByRoleIds([FromBody]List<string> roleIds)
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetOrganizationsWithUsersByRoleIds(roleIds);
            });
        }

        /// <summary>
        /// 根据用户Id，获取其所属部门及下属员工
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetOrganizationsWithUsersByUserId")]
        public ServiceResult<List<OrganizationDTO>> GetOrganizationsWithUsersByUserId(string userId)
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetOrganizationsWithUsersByUserId(userId);
            });
        }

        /// <summary>
        /// 获取角色及部门下的所有部门及其下属员工
        /// </summary>
        /// <param name="searchModel">
        /// roleIds：角色Id列表
        /// depIds：部门Id列表
        /// </param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetOrgsWithUsersByRoleIdsAndOrgids")]
        public ServiceResult<List<OrganizationDTO>> GetOrgsWithUsersByRoleIdsAndOrgids([FromBody]RootOrgWithUsersSearchDTO searchModel)
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetOrgsWithUsersByRoleIdsAndOrgids(searchModel.RoleIds, searchModel.DepIds);
            });
        }


        /// <summary>
        /// 获取部门下和员工(erp)
        /// </summary>
        /// <param name="searchModel">
        /// roleIds：角色Id列表
        /// depIds：部门Id列表
        /// </param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetPaginatedRootOrganizationsWithUsersByFilter")]
        public ServiceResult<PaginatedBaseDTO<OrganizationDTO>> GetPaginatedRootOrganizationsWithUsersByFilter([FromBody]RootOrgWithUsersPaginatedSearchDTO searchModel)
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetPaginatedOrganizationsWithUsersByFilter(searchModel.Appid, searchModel.RoleIds, searchModel.DepartName, searchModel.DepartCode, searchModel.UserName, searchModel.UserCode, searchModel.SearchKey, searchModel.PageIndex, searchModel.PageSize);
            });
        }

        /// <summary>
        /// 获取分页的部门及其下属员工数据
        /// </summary>
        /// <param name="searchModel"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetPaginatedOrganizationsWithUsersByFilter")]
        public ServiceResult<PaginatedBaseDTO<OrganizationDTO>> GetPaginatedOrganizationsWithUsersByFilter([FromBody]RootOrgWithUsersPaginatedSearchDTO searchModel)
        {
            return GetServiceResult(() =>
            {
                return SysManageService.GetPaginatedOrganizationsWithUsersByFilter(searchModel.Appid, searchModel.RoleIds,
                        searchModel.DepartName, searchModel.DepartCode, searchModel.UserName, searchModel.UserCode, searchModel.SearchKey, searchModel.PageIndex, searchModel.PageSize);
            });
        }

        /// <summary>
        /// 获取所有的用户
        /// </summary>
        /// <param name="page"></param>
        /// <param name="rows"></param>
        /// <param name="email"></param>
        /// <param name="phone"></param>
        /// <param name="name"></param>
        /// <param name="statType"></param>
        /// <param name="positionLevel"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetAllUser")]
        public ServiceResult<PaginatedBaseDTO<UserDTO>> GetAllUser(
            int page = 1, int rows = 10, string email = "", string phone = "", string name = "", string statType = "", PositionLevel? positionLevel = null)
        {
            return GetServiceResult(() =>
            {
                return AccountService.GetPaginatedUsersByFilter(page, rows, email, phone, name, statType, positionLevel);
            });
        }

        /// <summary>
        /// 根据部门范围获取其下人员
        /// </summary>
        /// <param name="startDeptFid">开始部门</param>
        /// <param name="endDeptFid">结束部门</param>
        /// <param name="page"></param>
        /// <param name="rows"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetUsersByOrgRange")]
        public ServiceResult<PaginatedBaseDTO<UserDTO>> GetUsersByOrgRange(Guid startDeptFid, Guid endDeptFid, int page, int rows)
        {
            return GetServiceResult(() =>
            {
                List<UserDTO> userList;
                //无部门范围时,可选择所有人员--所有挂在部门下的人
                //if (startDeptFid.Equals(Guid.Empty) && endDeptFid.Equals(Guid.Empty))
                //{
                //    userList = AccountService.FindAllUsersNoInclude();
                //}
                //else
                //{
                userList = SysManageService.GetUsersByOrgRange(startDeptFid, endDeptFid);
                //}

                if (userList.Count > 0)
                {
                    var data = userList.Skip(page - 1).Take(rows).ToList();
                    return new PaginatedBaseDTO<UserDTO>(page, rows, userList.Count, data);
                }
                else
                {
                    return new PaginatedBaseDTO<UserDTO>();
                }
            });
        }

        #endregion
    }
}
